package jtech;

import static jtech.Constantes.MOUSE_BUTTON_LEFT;
import static jtech.Constantes.MOUSE_BUTTON_MIDDLE;
import static jtech.Constantes.MOUSE_BUTTON_RIGHT;
import static jtech.Constantes.MOUSE_MOVE_DOWN;
import static jtech.Constantes.MOUSE_MOVE_LEFT;
import static jtech.Constantes.MOUSE_MOVE_RIGHT;
import static jtech.Constantes.MOUSE_MOVE_UP;
import static jtech.Constantes.MOUSE_WHEEL_DOWN;
import static jtech.Constantes.MOUSE_WHEEL_UP;

import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;

/**
 * The InputManager manages input of key and mouse events. Events are mapped to
 * GameActions.
 */
public class Input2 {
    
	private static final int NUM_MOUSE_CODES = 10;

	// key codes are defined in java.awt.KeyEvent.
	// most of the codes (except for some rare ones like
	// "alt graph") are less than 600.
	private static final int NUM_KEY_CODES = 600;

	private GameAction[] keyActions = new GameAction[NUM_KEY_CODES];
	private GameAction[] mouseActions = new GameAction[NUM_MOUSE_CODES];
	
	/**
	 * Maps a GameAction to a specific key. The key codes are defined in
	 * java.awt.KeyEvent. If the key already has a GameAction mapped to it, the
	 * new GameAction overwrites it.
	 */
	public void mapToKey(GameAction gameAction, int keyCode) {
		keyActions[keyCode] = gameAction;
	}

	/**
	 * Maps a GameAction to a specific mouse action. The mouse codes are defined
	 * herer in InputManager (MOUSE_MOVE_LEFT, MOUSE_BUTTON_1, etc). If the
	 * mouse action already has a GameAction mapped to it, the new GameAction
	 * overwrites it.
	 */
	public void mapToMouse(GameAction gameAction, int mouseCode) {
		mouseActions[mouseCode] = gameAction;
	}

	/**
	 * Clears all mapped keys and mouse actions to this GameAction.
	 */
	public void clearMap(GameAction gameAction) {
		for (int i = 0; i < keyActions.length; i++) {
			if (keyActions[i] == gameAction) {
				keyActions[i] = null;
			}
		}

		for (int i = 0; i < mouseActions.length; i++) {
			if (mouseActions[i] == gameAction) {
				mouseActions[i] = null;
			}
		}

		gameAction.reset();
	}

	/**
	 * Gets a List of names of the keys and mouse actions mapped to this
	 * GameAction. Each entry in the List is a String.
	 */
	public List<String> getMaps(GameAction gameCode) {
		ArrayList<String> list = new ArrayList<String>();

		for (int i = 0; i < keyActions.length; i++) {
			if (keyActions[i] == gameCode) {
				list.add(getKeyName(i));
			}
		}

		for (int i = 0; i < mouseActions.length; i++) {
			if (mouseActions[i] == gameCode) {
				list.add(getMouseName(i));
			}
		}
		return list;
	}

	/**
	 * Resets all GameActions so they appear like they haven't been pressed.
	 */
	public void resetAllGameActions() {
		for (int i = 0; i < keyActions.length; i++) {
			if (keyActions[i] != null) {
				keyActions[i].reset();
			}
		}

		for (int i = 0; i < mouseActions.length; i++) {
			if (mouseActions[i] != null) {
				mouseActions[i].reset();
			}
		}
	}

	private GameAction getKeyAction(KeyEvent e) {
		int keyCode = e.getKeyCode();
		return (keyCode < keyActions.length) ? keyActions[keyCode] : null;
	}

	

	// implement KeyListener
	public void keyPressed(KeyEvent ke) {
		GameAction gameAction = getKeyAction(ke);
		if (gameAction != null) {
			gameAction.press();
		}
		ke.consume();
	}

	public void keyReleased(KeyEvent ke) {
		GameAction gameAction = getKeyAction(ke);
		if (gameAction != null) {
			gameAction.release();
		}
		ke.consume();
	}
	
	public void keyTyped(KeyEvent ke) {
		ke.consume();
	}

	public void mouseHelper(int codeNeg, int codePos, int amount) {
		GameAction gameAction;
		if (amount < 0) {
			gameAction = mouseActions[codeNeg];
		} else {
			gameAction = mouseActions[codePos];
		}
		if (gameAction != null) {
			gameAction.press(Math.abs(amount));
			gameAction.release();
		}
	}
	
   /**
     * Gets the name of a key code.
     */
    public static String getKeyName(int keyCode) {
        return KeyEvent.getKeyText(keyCode);
    }
	
    
    /**
     * Gets the name of a mouse code.
     */
    public static String getMouseName(int mouseCode) {
        switch (mouseCode) {
            case MOUSE_MOVE_LEFT:
                return "Mouse Left";
            case MOUSE_MOVE_RIGHT:
                return "Mouse Right";
            case MOUSE_MOVE_UP:
                return "Mouse Up";
            case MOUSE_MOVE_DOWN:
                return "Mouse Down";
            case MOUSE_WHEEL_UP:
                return "Mouse Wheel Up";
            case MOUSE_WHEEL_DOWN:
                return "Mouse Wheel Down";
            case MOUSE_BUTTON_LEFT:
                return "Mouse Button Left";
            case MOUSE_BUTTON_MIDDLE:
                return "Mouse Button Middle";
            case MOUSE_BUTTON_RIGHT:
                return "Mouse Button Right";
        }
        return "Unknown mouse code " + mouseCode;
    }
	
}
